package utils

import (
	"sync"
	"time"
)

// Task 定义任务的接口
type Task interface {
	Execute()
}

// Pool 协程池
type Pool struct {
	JobQueue       chan Task
	MaxWorkers     int
	MinWorkers     int
	CurrentWorkers int
	mu             sync.Mutex
	wg             sync.WaitGroup
}

// NewPool 创建一个协程池
func NewPool(maxWorkers, minWorkers, jobQueueSize int) *Pool {
	pool := &Pool{
		JobQueue:       make(chan Task, jobQueueSize),
		MaxWorkers:     maxWorkers,
		MinWorkers:     minWorkers,
		CurrentWorkers: minWorkers,
	}
	// 启动最小数量的协程
	pool.wg.Add(minWorkers)
	for i := 0; i < minWorkers; i++ {
		go pool.worker()
	}

	// 启动调度协程
	go pool.monitor()

	return pool
}

// Submit 提交任务到协程池
func (p *Pool) Submit(task Task) {
	p.JobQueue <- task
}

// worker 工作协程
func (p *Pool) worker() {
	defer p.wg.Done()
	for {
		select {
		case task := <-p.JobQueue:
			if task == nil {
				return
			}
			task.Execute()
		}
	}
}

// monitor 调度协程，用于动态调整协程池大小
func (p *Pool) monitor() {
	for {
		time.Sleep(time.Second * 5) // 每隔5秒检查一次
		p.mu.Lock()
		// 获取当前任务队列长度
		queueLength := len(p.JobQueue)

		if p.CurrentWorkers < p.MaxWorkers && float64(queueLength) > 1.5*float64(p.CurrentWorkers) {
			for i := 0; i < queueLength; i++ {
				go p.worker()
				p.CurrentWorkers++
				p.wg.Add(1)
			}
		} else if queueLength < p.MinWorkers && p.CurrentWorkers > p.MinWorkers {
			diff := p.CurrentWorkers - p.MinWorkers
			for i := 0; i < diff; i++ {
				p.JobQueue <- nil
				p.CurrentWorkers--
			}
		}
		p.mu.Unlock()
	}
}

// Wait 等待所有任务完成
func (p *Pool) Wait() {
	close(p.JobQueue)
	p.wg.Wait()
}
